using Microsoft.Extensions.Logging;

namespace DocumentCreationSystem.Services.AgentOps
{
    /// <summary>
    /// AgentOps事件总线接口
    /// </summary>
    public interface IAgentOpsEventBus
    {
        /// <summary>
        /// 发布事件
        /// </summary>
        /// <typeparam name="T">事件类型</typeparam>
        /// <param name="eventData">事件数据</param>
        Task PublishAsync<T>(T eventData) where T : class;

        /// <summary>
        /// 订阅事件
        /// </summary>
        /// <typeparam name="T">事件类型</typeparam>
        /// <param name="handler">事件处理器</param>
        void Subscribe<T>(Func<T, Task> handler) where T : class;

        /// <summary>
        /// 取消订阅事件
        /// </summary>
        /// <typeparam name="T">事件类型</typeparam>
        /// <param name="handler">事件处理器</param>
        void Unsubscribe<T>(Func<T, Task> handler) where T : class;
    }

    /// <summary>
    /// AgentOps缓存服务接口
    /// </summary>
    public interface IAgentOpsCacheService
    {
        /// <summary>
        /// 获取缓存值
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="key">缓存键</param>
        /// <returns>缓存值</returns>
        Task<T?> GetAsync<T>(string key) where T : class;

        /// <summary>
        /// 设置缓存值
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="key">缓存键</param>
        /// <param name="value">缓存值</param>
        /// <param name="expiration">过期时间</param>
        Task SetAsync<T>(string key, T value, TimeSpan? expiration = null) where T : class;

        /// <summary>
        /// 删除缓存值
        /// </summary>
        /// <param name="key">缓存键</param>
        Task RemoveAsync(string key);

        /// <summary>
        /// 检查缓存是否存在
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <returns>是否存在</returns>
        Task<bool> ExistsAsync(string key);
    }

    /// <summary>
    /// AgentOps事件总线实现
    /// </summary>
    public class AgentOpsEventBus : IAgentOpsEventBus
    {
        private readonly ILogger<AgentOpsEventBus> _logger;
        private readonly Dictionary<Type, List<Func<object, Task>>> _handlers = new();

        public AgentOpsEventBus(ILogger<AgentOpsEventBus> logger)
        {
            _logger = logger;
        }

        public async Task PublishAsync<T>(T eventData) where T : class
        {
            var eventType = typeof(T);
            
            if (_handlers.TryGetValue(eventType, out var handlers))
            {
                var tasks = handlers.Select(handler => handler(eventData));
                await Task.WhenAll(tasks);
                
                _logger.LogDebug($"已发布事件 {eventType.Name}，处理器数量: {handlers.Count}");
            }
            else
            {
                _logger.LogDebug($"没有找到事件 {eventType.Name} 的处理器");
            }
        }

        public void Subscribe<T>(Func<T, Task> handler) where T : class
        {
            var eventType = typeof(T);
            
            if (!_handlers.ContainsKey(eventType))
            {
                _handlers[eventType] = new List<Func<object, Task>>();
            }
            
            _handlers[eventType].Add(obj => handler((T)obj));
            
            _logger.LogDebug($"已订阅事件 {eventType.Name}");
        }

        public void Unsubscribe<T>(Func<T, Task> handler) where T : class
        {
            var eventType = typeof(T);
            
            if (_handlers.TryGetValue(eventType, out var handlers))
            {
                // 注意：这里的实现比较简单，实际应用中可能需要更复杂的处理器匹配逻辑
                handlers.RemoveAll(h => h.Method == handler.Method);
                
                _logger.LogDebug($"已取消订阅事件 {eventType.Name}");
            }
        }
    }

    /// <summary>
    /// AgentOps缓存服务实现
    /// </summary>
    public class AgentOpsCacheService : IAgentOpsCacheService
    {
        private readonly ILogger<AgentOpsCacheService> _logger;
        private readonly Dictionary<string, (object Value, DateTime Expiry)> _cache = new();

        public AgentOpsCacheService(ILogger<AgentOpsCacheService> logger)
        {
            _logger = logger;
        }

        public Task<T?> GetAsync<T>(string key) where T : class
        {
            if (_cache.TryGetValue(key, out var entry))
            {
                if (entry.Expiry > DateTime.Now)
                {
                    _logger.LogDebug($"缓存命中: {key}");
                    return Task.FromResult(entry.Value as T);
                }
                else
                {
                    _cache.Remove(key);
                    _logger.LogDebug($"缓存已过期: {key}");
                }
            }

            _logger.LogDebug($"缓存未命中: {key}");
            return Task.FromResult<T?>(null);
        }

        public Task SetAsync<T>(string key, T value, TimeSpan? expiration = null) where T : class
        {
            var expiryTime = DateTime.Now.Add(expiration ?? TimeSpan.FromMinutes(30));
            _cache[key] = (value, expiryTime);

            _logger.LogDebug($"已设置缓存: {key}，过期时间: {expiration?.TotalMinutes ?? 30}分钟");

            return Task.CompletedTask;
        }

        public Task RemoveAsync(string key)
        {
            _cache.Remove(key);

            _logger.LogDebug($"已删除缓存: {key}");

            return Task.CompletedTask;
        }

        public Task<bool> ExistsAsync(string key)
        {
            var exists = _cache.ContainsKey(key) && _cache[key].Expiry > DateTime.Now;

            _logger.LogDebug($"缓存存在检查: {key} = {exists}");

            return Task.FromResult(exists);
        }
    }
}
